﻿Imports System.IO
Imports System.Drawing
Imports System.Drawing.Text
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Threading
Imports System.Windows.Forms

Public Class VM
    Dim WithEvents vmf As New MDI1

#Region "Keywords"
    Dim Comment = 1
    Dim Push = 2
    Dim PushString = 3
    Dim Print = 4
    Dim Halt = 5
    Dim WaitForKey = 6
    Dim ClearScreen = 7
    Dim WaitTime = 8
    Dim Show = 9
#End Region
    Shared stack As New List(Of Object)()
    Private Class var
        Public Name As String
        Public Index As Integer
    End Class
    Private Sub Run(il As String, g As Object)
        Dim jump As Boolean = False
        Dim variables As Object() = New Object(999999) {}
        Dim [CALL] As Boolean = True
        'il = il.Replace((ChrW(13)).ToString(), "")
        Dim lbl As String = ""
        Dim line = 0
Begin:
        For Each cmd As String In il.Split(vbLf)
            'If cmd.StartsWith(" ") Then
            If cmd.EndsWith(" ") Then

            End If
            'End If
            If cmd.StartsWith("push ") Then
                stack.Add(cmd.Substring(5))
            End If
            If cmd.StartsWith("push$ ") Then
                stack.Add(cmd.Substring(6))
            End If
            If cmd.StartsWith("prt") Then
                'stack.Pop()
              
                For Each abc In stack
                    'Console.Write(abc)
                    scr.Text += abc
                Next
                stack.Clear()
                'Console.Write(vbNewLine)
                scr.Text += vbNewLine
            End If
            If cmd = "hlt" Then
                'Console.Read()

                Exit Sub
            End If
            If (cmd.StartsWith("wait ")) Then
                Dim msTime As Int32 = Int32.Parse(cmd.Substring(5))
                Thread.Sleep(msTime)
            End If
            If cmd.StartsWith("show ") Then
                Dim message1 As String = cmd.Substring(5)
                Dim inch = False
                Dim chn As Int32
                Dim message As String
                For Each ch As Char In message1
                    If Not inch Then
                        If ch = "#" Then
                            inch = True
                        Else
                            message = message & ch
                        End If
                    Else
                        If IsNumeric(ch) Then
                            chn = chn & ch
                        ElseIf ch = "#" Then
                            message = message + Chr(chn)
                            chn = Nothing
                            inch = False
                        Else
                            Exit Sub
                        End If
                    End If
                Next

                MessageBox.Show("Program sent:" + Chr(13) + Chr(13) + message)
            End If
            If cmd.StartsWith("frm ") Then
                Dim pars As String()
                Dim pars1 As String = cmd.Substring(5)
                pars = pars1.Split(" ")
                Dim x As Int32 = pars(0)
                Dim y As Int32 = pars(1)
                Dim width As Int32 = pars(2)
                Dim height As Int32 = pars(3)
                Dim title As String = pars(4)
                Dim frm As New Form
                frm.Location = New Point(x, y)
                frm.Text = title
                frm.MdiParent = vmf
                frm.Show()
            End If
            If cmd = "wfk" Then
                Console.ReadKey()
                End
            End If
            If cmd = "cls" Then
                scr.Clear()
            End If
Skip:
            Console.Write("")
            line = line + 1
        Next
    End Sub

    Public Sub Run(Dir As [String])
        Dim br As New BinaryReader(New FileStream(Dir, FileMode.Open))
        Dim Out As String = ""

        If br.ReadString() = "FLSCRIPT" Then
        Else
            MsgBox("Not a valid FlowScript file!")
            Exit Sub
        End If
        While True
            Try
                Dim OpCode As Integer = br.ReadInt32()
                If OpCode = PushString Then
                    Out += "push$ " & br.ReadString()
                End If
                If OpCode = Push Then
                    Out += "push " & br.ReadInt32().ToString()
                End If
                If OpCode = Print Then
                    Out += "prt"
                End If
                If OpCode = WaitTime Then
                    Out += "wait " & br.ReadString()
                End If
                If OpCode = Show Then
                    Out += "show " & br.ReadString()
                End If
                If OpCode = Halt Then
                    Out += "hlt"
                End If
                If OpCode = WaitForKey Then
                    Out += "wfk"
                End If
                If OpCode = ClearScreen Then
                    Out += "cls"
                End If
                If Not Out = "" Then
                    Out += vbLf
                End If

            Catch
                Exit While
            End Try
        End While
        Run(Out, "")
    End Sub

    Private Sub VM_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        MyBase.Show()
        vmf.Location = New Point(Me.Location.X + Me.Width, Me.Location.Y)
        vmf.Show()
    End Sub

    Sub Wait(milli As Long)
        Threading.Thread.Sleep(milli)
    End Sub

    Public Sub Load(filepath As String)
        If Not filepath.EndsWith(".fsx") Then
            scr.Text = "Invalid program file"
        Else
            Try

                Run(filepath)

            Catch ex As Exception

            End Try
        End If
    End Sub


    Public Function StringToBin(text As String) As String
        Dim oReturn As New StringBuilder
        Dim Separator As String = ("")
        For Each Character As Byte In ASCIIEncoding.ASCII.GetBytes(text)
            oReturn.Append(Convert.ToString(Character, 2).PadLeft(8, "1"))
            oReturn.Append(Separator)
        Next
        Return oReturn.ToString
    End Function


    Public Function BinToString(binary As String) As String
        Dim BinaryText As String = binary
        Dim Characters As String = Regex.Replace(BinaryText, "[^01]", "")
        Dim ByteArray((Characters.Length / 8) - 1) As Byte
        For Index As Integer = 0 To ByteArray.Length - 1
            ByteArray(Index) = Convert.ToByte(Characters.Substring(Index * 8, 8), 2)
        Next
        Return (ASCIIEncoding.ASCII.GetString(ByteArray))
    End Function

    Private Sub LoadAProgramFileToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles LoadAProgramFileToolStripMenuItem.Click
        For Each f As Form In vmf.MdiChildren
            f.Close()
        Next
        If ofp.ShowDialog = Windows.Forms.DialogResult.OK Then
            If File.Exists(ofp.FileName) Then
                If ofp.FileName.EndsWith(".fsx") Then
                    Load(ofp.FileName)
                ElseIf ofp.FileName.EndsWith(".fsc") Then
                    scr.Clear()
                    Run(File.ReadAllText(ofp.FileName), "")
                End If
            End If
        End If
    End Sub

    Private Sub VM_LocationChanged(sender As Object, e As System.EventArgs) Handles Me.LocationChanged
        vmf.Location = New Point(Me.Location.X + Me.Width, Me.Location.Y)
    End Sub

    Private Sub VM_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
        Dim args As String() = Environment.GetCommandLineArgs()
        If args.Length = 1 Then
            'MsgBox("USAGE: irvm <path of file>", vbInformation, "Usage")
        Else
            If File.Exists(args(1)) Then
                If args(1).EndsWith(".fsx") Then
                    scr.Clear()
                    'Load(args(1))
                ElseIf args(1).EndsWith(".fsc") Then
                    scr.Clear()
                    Run(File.ReadAllText(args(1)), "")
                End If

            Else
                MsgBox("File doesn't exist!", vbExclamation, "Error")
            End If
        End If
    End Sub

   

    Private Sub vmf_LocationChanged(sender As Object, e As System.EventArgs) Handles vmf.LocationChanged
        Me.Location = New Point(vmf.Location.X - Me.Width, vmf.Location.Y)
    End Sub
End Class